/*******************************************************************************
 * Package: com.hngtrust.iir.third.service.impl
 * Type:    ChinaTrustRegistrationServiceImpl
 * Date:    2021/10/14 10:26
 *
 * Copyright (c) 2021 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.hngtrust.iir.fileclean.service.impl;
import com.hngtrust.clickhouse.notice.entity.EtlNoticeFile;
import com.hngtrust.clickhouse.notice.service.EtlNoticeFileService;
import com.hngtrust.clickhouse.report.entity.EtlReportFile;
import com.hngtrust.clickhouse.report.service.EtlReportFileService;
import com.hngtrust.iir.fileclean.service.FileCleanService;
import com.tiger.web.service.FileService;
import io.minio.ListObjectsArgs;
import io.minio.MinioClient;
import io.minio.Result;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * 公告研报文件多余miniio文件清除
 *
 * @author Yujiaqi
 * @date 2021/10/14 10:26
 */
@Service
@Slf4j
public class FileServiceServiceImpl implements FileCleanService {
    
    @Value("${tiger.minio.address}")
    private String address;
    
    @Value("${tiger.minio.username}")
    private String username;
    
    @Value("${tiger.minio.password}")
    private String password;
    
    @Autowired
    private FileService fileService;
    @Autowired
    private EtlNoticeFileService etlNoticeFileService;
    @Autowired
    private EtlReportFileService etlReportFileService;
    
    /**
     * 公告文件多余miniio文件清除
     */
    @Override
    public void queryNoticeFileCleanMiniio() throws Exception {
        //查询公告所有数据
        List<EtlNoticeFile> etlNoticeFiles = etlNoticeFileService.queryList(new EtlNoticeFile());
        List<String> list = new ArrayList<>();
        //获取etl_notice_file所有数据
        for (EtlNoticeFile etlNoticeFile : etlNoticeFiles) {
            String filePath = etlNoticeFile.getIirFilePath() + "/" + etlNoticeFile.getFileName();
            list.add(filePath);
        }
        log.info("处理后公告数据总数："+list.size());
        String bucketName = "iir";
        String startAfter = "etl/notice";
        List<String> list1 = new ArrayList<>();
        log.info("----------开始----------");
        List<String> folderList = getFolderList(bucketName,startAfter);
        Date date = new Date();
        log.info("----------删除miniio公告文件开始----------"+date);
        for (String s : folderList) {
            if (!list.contains(s)){
                //删除miniio文件
                try {
                    fileService.delete(s);
                    list1.add(s);
                    log.info("删除：{}"+s+"  公告文件，成功");
                }catch (Exception e){
                    log.error("删除：{}"+s+"  公告文件，失败");
                    continue;
                }
            }
        }
        Date date1 = new Date();
        log.info("----------删除miniio公告文件结束----------"+date1);
        long l = (date1.getTime() - date.getTime()) / 1000;
        log.info("共计删除："+list1.size()+" 个公告文件，共计用时"+l+"秒");
        log.info("----------结束----------");
    }
    
    /**
     * 研报文件多余miniio文件清除
     */
    @Override
    public void queryReportFileCleanMiniio() throws Exception {
        //查询研报所有数据
        List<EtlReportFile> etlReportFiles = etlReportFileService.queryList(new EtlReportFile());
        List<String> list = new ArrayList<>();
        //获取etl_report_file所有数据
        for (EtlReportFile etlReportFile : etlReportFiles) {
            String filePath = etlReportFile.getIirFilePath() + "/" + etlReportFile.getFileName();
            list.add(filePath);
        }
        log.info("处理后研报数据总数："+list.size());
        String bucketName = "iir";
        String startAfter = "etl/report";
        List<String> list1 = new ArrayList<>();
        log.info("----------开始----------");
        List<String> folderList = getFolderList(bucketName,startAfter);
        Date date = new Date();
        log.info("----------删除minio研报文件开始----------"+date);
        for (String s : folderList) {
            if (!list.contains(s)){
                //删除minio文件
                try {
                    fileService.delete(s);
                    list1.add(s);
                    log.info("删除：{}"+s+"  研报文件，成功");
                }catch (Exception e){
                    log.error("删除：{}"+s+"  研报文件，失败");
                    continue;
                }
            }
        }
        Date date1 = new Date();
        log.info("----------删除minio研报文件结束----------"+date1);
        long l = (date1.getTime() - date.getTime()) / 1000;
        log.info("共计删除："+list1.size()+" 个研报文件，共计用时"+l+"秒");
        log.info("----------结束----------");
    }
    
    /**
     * 获取指定bucketName下所有文件
     * @param bucketName
     * @return
     * @throws Exception
     */
    private List<String> getFolderList(String bucketName,String startAfter) throws Exception{
        // 连接miniio
        MinioClient minioClient = MinioClient.builder().endpoint(address).credentials(username, password).build();
        //递归查询桶下信息
        Date date = new Date();
        log.info("----------开始读取minio公告或研报的所有文件----------");
        ListObjectsArgs build = ListObjectsArgs.builder()
                                               .bucket(bucketName)
                                               .recursive(true).prefix(startAfter)
                                                .build();
        Iterable<Result<Item>> results = minioClient.listObjects(build);
        Iterator<Result<Item>> iterator = results.iterator();
        List<String> items = new ArrayList<>();
        while(iterator.hasNext()) {
            Item item = iterator.next().get();
            String itemUpdate = "/iir/"+item.objectName();
            items.add(itemUpdate);
            log.info("读取文件第:"+items.size()+"个，文件路径：{"+itemUpdate+"}");
        }
        Date date1 = new Date();
        long l = (date1.getTime() - date.getTime()) / 1000;
        log.info("----------查询文件共计用时"+l+"秒,读取文件"+items.size()+"个----------");
        log.info("----------结束读取minio公告或研报的所有文件----------");
        return items;
    }
    
    
}
